/*  __ ,
  ,-| ~
 ('||/__,               _     _
(( |||  | ,._-_  /'\\  / \\  / \\ '\\/\\
(( |||==|  ||   || || || || || ||  || ;'
 ( / |  ,  ||   || || || || || ||  ||/
  -____/   \\,  \\,/  \\_-| \\_-|  |/
                       /  \  /  \ (
                      '----`'----` -_-                                                  
                                         
-__ /\\                   ,              
  ||  \\  '         _    ||              
 /||__|| \\ ,._-_  < \, =||=  _-_   _-_, 
 \||__|| ||  ||    /-||  ||  || \\ ||_.  
  ||  |, ||  ||   (( ||  ||  ||/    ~ || 
_-||-_/  \\  \\,   \/\\  \\, \\,/  ,-_-  
  ||                                     
                               _
          ____________________(#)_____________________
         /                    |7                      /
        |    Grogy Pirates v0.1                      |
        |    Team ~ Team Salty Sea Dogs              |
        |    Engine ~ Scurvy v0.1                    |
		|    Genre ~ Action, Adventure, CO-OP        |
        |    Created ~ June 2, 2007                  |
        |    Modified ~ January 21, 2010             |
        |                                            |
		|                                            |
        |                                            |
         \    ________________________________________\__
          \__/##########################################/
*/

#include <irrlicht.h>
#include <iostream>
#include "scenetype.h"
#include "HUD.h"
#include "GUI.h"
#include "input.h"
#include "usermovement.h"

using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace std;



int main()
{
	MyEventReceiver receiver;
	//SmoothEventReceiver *receiver = SmoothEventReceiver.createReceiver();

	//Load Profile From Directory
	if( ! info )
		profile *info = new profile;
	else
	{
		//Read Saved Profile
		if( info->Name )
		//Write Default Profile
		else
		{
			info->Name	= "Black Beard";
			info->Mesh	= "media/Pirate.b3d";
			info->Skill	= "Buccaneers";
		}
	}
	
	IrrlichtDevice	*device = createDevice( profile::Video::DriverType,
		dimension2d<s32>( 640, 480 ), 16, false, false, false, &receiver );

	if( device == 0 )
		return 1; // could not create selected driver.

	array<SJoystickInfo> joystickInfo;
	if( device->activateJoysticks( joystickInfo ))
	{
		cout << "Joystick support is enabled and " << joystickInfo.size() << " joystick(s) are present." << endl;

		for( u32 joystick = 0; joystick < joystickInfo.size(); ++joystick)
		{
			cout << "Joystick " << joystick << ":" << endl;
			cout << "\tName: '" << joystickInfo[joystick].Name.c_str() << "'" << endl;
			cout << "\tAxes: " << joystickInfo[joystick].Axes << endl;
			cout << "\tButtons: " << joystickInfo[joystick].Buttons << endl;

			cout << "\tHat is: ";

			switch( joystickInfo[joystick].PovHat )
			{
			case SJoystickInfo::POV_HAT_PRESENT:
				cout << "present" << endl;
				break;

			case SJoystickInfo::POV_HAT_ABSENT:
				cout << "absent" << endl;
				break;

			case SJoystickInfo::POV_HAT_UNKNOWN:
			default:
				cout << "unknown" << endl;
				break;
			}
		}
	}
	else
	{
		cout << "Joystick support is not enabled." << endl;
	}

	stringw tmp = L"Scurvy v0.1(";
	tmp += joystickInfo.size();
	tmp += " joysticks )";
	device->setWindowCaption( tmp.c_str());
	
	/*
	We have done everything, so lets draw it. We also write the current
	frames per second and the name of the driver to the caption of the
	window.
	*/
	int lastFPS = -1;

	// In order to do framerate independent movement, we have to know
	// how long it was since the last frame
	u32 then = device->getTimer()->getTime();

	// This is the movemen speed in units per second.
	const f32 MOVEMENT_SPEED = 5.f;

	IVideoDriver        *driver	= device->getVideoDriver();
	ISceneManager       *smgr	= device->getSceneManager();
	IGUIEnvironment     *env    = device->getGUIEnvironment();

	while( device->run())
	{
		driver->beginScene( true, true, SColor( 255, 106, 181, 255 ));

		// Work out a frame delta time.
		const u32 now = device->getTimer()->getTime();
		const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
		then = now;

		/* Check if keys W, S, A or D are being held down, and move the
		sphere node around respectively. Multiply Delta Frame by Movement Speed
		*/

		//Game State
		switch( GamSte )
		{
			//Introduction
			case "Introduction":
                env->drawAll();
				break;

			//Loading
			case "Loading":
				map         *game = map::Initialize(
					profile::Lineup )
				RPGCamera	*camera = RPGCamera::Initialize(
					null,
					null,
					"Spectate",
					info->View[0] );
				user	    *player = user::Initialize(
					null,
					null,
					info->Mesh,
					info->Name,
					info->Skill,
					info->Weapon,
					info->Item );
				//camera->
				env->drawAll();
				break;

			//Playing
			case "Playing":
            	//Update Movement
				player->Update();

				//Update Camera
				camera->Update();
				//Line.setLineFromVects( Cam.Node.getAbsolutePosition(),
				//	Line.getStart().Plus(( Cam.Node.getTarget().Minus( Line.getStart())).normalize().Mult( 1000.0 )));

				//If( smgr.getSceneCollisionManager().getCollisionPoint(
				//	Line, Slc, Intersection, Tri ))
				//{
				//	driver->SetTransform( ETS_WORLD, Matrix4.create());
				//	driver->draw3DTriangle( user::Tri, Null );
				//}

                //Calculate Scene
				map->Update();
				effect::Update();

				//Render Scene
				smgr->drawAll();

				//Render HUD
				infoHUD( Amm, Hth, WpnInf, ItmInf, AphInd, ActTmr, ActAcc, Eqp );

				//Render GUI
				//env.drawAll();

				gameEvent( GamMde );
				break;

			//Accomplished
			case "Accomplished":

			//Failed
			case "Failed":

			//Paused
			case "Paused":
				env.drawAll();
				break;
			//Spectating
			case "Spectating":

			//Dead
			case "Dead":
			default:
		}

		if( profile.Debug )
		{
			FPS = driver->getFPS();
			if( LastFPS || FPS ) LastFPS = FPS;

			string Str = "Buccaneers - Irrlicht v1.6.1";
			string Str += " [ " + driver->getName() + " ]";
			string Str += " | FPS: " + LastFPS;

			vector3df UsrPos2 = user::Nde.getAbsolutePosition();
			vector3df CamPos2 = RPGCamera.Nde.getAbsolutePosition();
			float CamDstHrz2 = vector3df( UsrPos2.getX(), 0, UsrPos2.getZ()).getDistanceFrom( vector3df( CamPos2.getX(), 0, CamPos2.getZ()));
			float CamDstVrt2 = CamPos2.getY() - UsrPos2.getY();
			float FwdAng2 = vector2df( CamPos2.getX() - UsrPos2.getX(), CamPos2.getZ() - UsrPos2.getZ()).getAngle();

			string Str2 = "SrfAng: " + int( SrfAngTst );
			string Str2 += " | TriCnt: " + driver->getPrimitiveCountDrawn();
			//Str2$ += " | Spd: " + Vector2df.createFromVals( user::Vel.getX(), user::Vel.getZ()).getLength();
			//Str2$ += " | NdeRot: " + user::Nde.GetRotation().getY();
			//Str2$ += " | MotVelRot: " + MotVelTst.getY();
			//Str2$ += " | MotVelAng: " + Int( MotVelTst.getX()) + ", " + Int( MotVelTst.getY()) + ", " + Int( MotVelTst.getZ());
			string Str2 += " | LndPos: " + int( LndPosTst.getX()) + ", " + int( LndPosTst.getY()) + ", " + int( LndPosTst.getZ());
			//Str2$ += " | CrsAng: " + CrsAng;
			//Str2$ += " | TriNrm: " + TriNrm.normalize().getX() + ", " + TriNrm.normalize().getY() + ", " + TriNrm.normalize().getZ();
			//Str2$ += " | Landed: " + FallTest;
			//Str2$ += " | Bumped: " + BumpTest;
			//Str2$ += " | FwdAng: " + FwdAng2;
			//Str2$ += " | AphInd: " + AphInd[1];
			//Str2$ += " | ActTmr: " + ActTmr[0];
			//Str2$ += " | Prj: " + projectile.Cnt.Count();
			//Str2$ += " | CamDstHrz: " + CamDstHrz2;
			//Str2$ += " | CamDstVrt: " + CamDstVrt2;
			//Str2$ += " | NdeRot: " + user::Nde.GetRotation().getY();
			//Str2$ += " | Position: " + Int( user::Nde.getPosition().getX()) + ", "  + Int( user::Nde.getPosition().getY()) + ", " + Int( user::Nde.getPosition().getZ());
			string Str2 += " | State: " + user::Ste;
			string Str2 += " | Vlc: " + int( user::Vlc.getX()) + ", " + int( user::Vlc.getY()) + ", " + int( user::Vlc.getZ());

			//Render Debug Information
			SMaterial LinMat = SMaterial.Create();

			LinMat.setFlag( EMF_LIGHTING, False );
			driver->setMaterial( LinMat );

			driver->draw3DTriangle( user::Tri, _SCOLOR( 255, 255, 255, 255 ));
			driver->draw3DLine( user::Nde.getAbsolutePosition(), user::Nde.getAbsolutePosition().Plus( user::Vlc.Mult( 20 )), _SCOLOR( 255, 255, 0, 0 ));
			driver->draw3DLine( user::Nde.getAbsolutePosition(), user::Nde.getAbsolutePosition().Minus( MotVlcTst ), _SCOLOR( 255, 0, 0, 255 ));
			driver->draw3DLine( user::Nde.getAbsolutePosition(), LndPosTst, SColor.createFromVals( 255, 0, 255, 0 ));
			GUIFont.draw( Str,
				rect<s32>( 0, 0, 256, 12 ),
				SColor( 255, 255, 255, 255 ));
			GUIFont.draw( "Debug Information:",
				rect<s32>( 0, 12, 256, 24 ),
				SColor( 255, 255, 255, 255 ));
			GUIFont.draw( Str2,
				rect<s32>( 0, 24, 256, 36 ),
				SColor( 255, 255, 255, 255 ));
		}
		driver->EndScene();
	}
	device->drop();

	return 1;
};
